var Pano = {
	"scenes" : null,
	"current": null,
	"switches" : {
		"wireframe" : false,
		"controls" : "pano",
		"scene" : 0
	},
	"stats":null,
	"controls" : false,
	"panoControls" : false,
	"orbitControls" : false,
	"camera" : null,
	"renderer" : null,
	"scene" : null,
	"mouse" : null,
	"waypoints" : [],
	"eventlistener" : []
};

Pano.addEventListener = function(e){
	Pano.eventlistenr.push(e);
};

Pano.onWindowResize = function(){
	Pano.camera.aspect = window.innerWidth / window.innerHeight;
	Pano.renderer.setSize(window.innerWidth,window.innerHeight);
};

Pano.onDocumentClick = function(x,y){
	mouse = normalizeMouse(x,y);
	raycaster = new THREE.Raycaster();
	raycaster.setFromCamera( mouse, Pano.camera );
	for(i = 0; i < Pano.waypoints.length; i++){
		is = raycaster.intersectObject(Pano.waypoints[i]);
		if(is.length > 0){
			Pano.switchToScene(Pano.scenes[Pano.current].waypoints[i].linkTo);
			break;
		}
	}
};

function normalizeMouse(x,y){
	v = new THREE.Vector2();
	v.x = (x / Pano.renderer.domElement.width) * 2 - 1;
	v.y = - (y / Pano.renderer.domElement.height) * 2 + 1;
	return v;
}

Pano.contextMenuListener = function(e){
	e.preventDefault();
	Pano.mouse = normalizeMouse(e.clientX,e.clientY);
	Pano.controls.enabled = false;
	$("#waypointbtn").click(Pano.addWaypointBtnClicked);
	$('#dialog').dialog("open");
	return false;
};

Pano.addWaypoint = function(v3){
	map = THREE.ImageUtils.loadTexture("pics/arrow.png");
	var material = new THREE.SpriteMaterial({
		map : map,
		color : 0xffffff,
		fog : true
	});
	var sprite = new THREE.Sprite(material);
	sprite.scale.set(16,16,16);
	sprite.position.copy(v3);
	Pano.scene.add(sprite);
	Pano.waypoints.push(sprite);
	return sprite;
};

Pano.addWaypointBtnClicked = function(e){
	raycaster = new THREE.Raycaster();
	raycaster.setFromCamera( Pano.mouse, Pano.camera );

	var intersects = raycaster.intersectObject(Pano.objSphere,true);
	if (intersects.length > 0) {
		Pano.addWaypoint(intersects[0].point);
	}
	Pano.controls.enabled = true;
	$("#dialog").dialog("close");
};

Pano.updateTitleNDescription = function(){
	if(typeof(Pano.scenes[Pano.current].title) === "undefined"){
		$('#title').text(" ");
	} else {
		$('#title').text(Pano.scenes[Pano.current].title);
	}
	if(typeof(Pano.scenes[Pano.current].description) === "undefined"){
		$('#description').text(" ");
	} else {
		$('#description').text(Pano.scenes[Pano.current].description);
	}
};

Pano.updateSoundtrack = function(){
	var src = Pano.scenes[Pano.current].soundtrack;
	var audio = document.getElementById("audio");
	if( src === undefined || src === null){
		audio.pause();
		return;
	}
	if(decodeURI(audio.src).lastIndexOf(src) < 0){
		console.log("change audio src from " + decodeURI(audio.src) + " to " + src);
		audio.src=src;
		audio.loop = true;
		audio.play();
	}
};

Pano.initPanoScene = function(){
	Pano.eventlistener.push(Pano.updateScene);
	Pano.eventlistener.push(Pano.updateTitleNDescription);
	Pano.eventlistener.push(Pano.updateSoundtrack);

	Pano.scene = new THREE.Scene();
	Pano.camera = new THREE.PerspectiveCamera(75,window.innerWidth/window.innerHeight,0.1,2000);
	Pano.scene.add(Pano.camera);

	var axis = new THREE.AxisHelper(500);
	Pano.scene.add(axis);

	var ambientLight = new THREE.AmbientLight(0xffffff);
	Pano.scene.add(ambientLight);

	var objSphereGeometry = new THREE.SphereGeometry(300,16,16);
	var objSphereMaterial = new THREE.MeshBasicMaterial({transparent : true,visible:false,side:THREE.DoubleSide,opacity:0});
	Pano.objSphere = new THREE.Mesh(objSphereGeometry,objSphereMaterial);
	Pano.objSphere.position.copy(Pano.scene.position);
	Pano.scene.add(Pano.objSphere);

	var sg = new THREE.SphereGeometry(500,46,46);
	sg.applyMatrix( new THREE.Matrix4().makeScale( -1, 1, 1 ) );
	Pano.wire = new THREE.MeshBasicMaterial({side:THREE.DoubleSide, wireframe : Pano.switches.wireframe, color : 0xff4444});
	Pano.sm = new THREE.MeshBasicMaterial({side:THREE.DoubleSide});
	var sphere = THREE.SceneUtils.createMultiMaterialObject(sg,[Pano.wire,Pano.sm]);
	sphere.position.copy(Pano.scene.position);
	Pano.scene.add(sphere);

	Pano.renderer = new THREE.WebGLRenderer();
	Pano.renderer.setSize(window.innerWidth, window.innerHeight);
	Pano.renderer.setClearColor(new THREE.Color(0xffffff));
	$('#content3d').append(Pano.renderer.domElement);
	//Pano.initStats("stats");
	Pano.mouse = new THREE.Vector2();
	document.oncontextmenu = Pano.contextMenuListener; 
};


Pano.animate = function(){
	animate();
	function animate(){
		requestAnimationFrame(animate);
		Pano.render();
	}
};

Pano.render = function(){
	Pano.renderer.render(Pano.scene,Pano.camera);
};

Pano.switchToScene = function(index){
	if(Pano.current != index){
		Pano.current = index;
		Pano.eventlistener.forEach(function(e){
			e();
		});
	}
};

Pano.updateScene = function(){
	var tex = THREE.ImageUtils.loadTexture(Pano.scenes[Pano.current].picture);
	tex.wrapS = THREE.MirroredRepeatWrapping;
	tex.wrapT = THREE.MirroredRepeatWrapping;
	tex.repeat.set(1,1);
	Pano.sm.map = tex;

	Pano.waypoints.forEach(function(e){
		Pano.scene.remove(e);
	});
	Pano.waypoints = [];

	
	Pano.scenes[Pano.current].waypoints.forEach(function(e){
		sp = Pano.addWaypoint(latAndLonToVector(e.at.lat,e.at.lon,300));
	});
	Pano.switchControls();
};

function latAndLonToVector(lat,lon,radius){
	lat = Math.max( - 85, Math.min( 85, lat ) );
	phi = THREE.Math.degToRad( 90 - lat );
	theta = THREE.Math.degToRad( lon );
	var vector = new THREE.Vector3();
	vector.x = radius * Math.sin( phi ) * Math.cos( theta );
	vector.y = radius * Math.cos( phi );
	vector.z = radius * Math.sin( phi ) * Math.sin( theta );
	return vector;
}

Pano.initStats = function(containerId){
	var stats = new Stats();
	stats.setMode(0);
	stats.domElement.style.position = "absolute";
	stats.domElement.style.left = "0px";
	stats.domElement.style.top = "0px";
	document.getElementById(containerId).appendChild(stats.domElement);
	Pano.stats = stats;
};

Pano.switchControls = function(){
	Pano.controls.enabled = false;
	switch(Pano.switches.controls){
		case "pano":
			Pano.camera.position.set(0,0,0);
			if(Pano.panoControls){
				Pano.panoControls.enabled = true;
			} else{
				Pano.panoControls = new THREE.PanoramaControls(Pano.camera);
			}
			Pano.panoControls.setLatNLon(Pano.scenes[Pano.current].lookAt.lat,Pano.scenes[Pano.current].lookAt.lon);
			Pano.controls = Pano.panoControls;
			break;
		case "orbit":
			Pano.camera.position.set(800,800,800);
			Pano.camera.lookAt(new THREE.Vector3(0,0,0));
			if(Pano.orbitControls){
				Pano.orbitControls.enabled = true;
			} else{
				Pano.orbitControls = new THREE.OrbitControls(Pano.camera);
				Pano.orbitControls.addEventListener('change',Pano.render);
			}
			Pano.controls = Pano.orbitControls;
			break;
		default:
			break;
	}
};


